package com.info.zhiduoduo.core.service.impl;

import com.baomidou.mybatisplus.mapper.Condition;
import com.info.zhiduoduo.common.CeoNoticeType;
import com.info.zhiduoduo.common.utils.DateUtil;
import com.info.zhiduoduo.common.utils.LogUtil;
import com.info.zhiduoduo.core.dto.dingdingnotice.GroupCode;
import com.info.zhiduoduo.core.service.CommonService;
import com.info.zhiduoduo.core.service.DingdingNoticeService;
import com.info.zhiduoduo.repository.dto.company.CompanyBriefDto;
import com.info.zhiduoduo.repository.dto.company.CompanyManagerDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerBriefDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerCompanyExpireDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerExpireDto;
import com.info.zhiduoduo.repository.entity.company.Company;
import com.info.zhiduoduo.repository.entity.company.CompanyProject;
import com.info.zhiduoduo.repository.entity.maker.Maker;
import com.info.zhiduoduo.repository.entity.maker.MakerAccount;
import com.info.zhiduoduo.repository.entity.maker.MakerStudio;
import com.info.zhiduoduo.repository.entity.notice.CeoNoticeRecord;
import com.info.zhiduoduo.repository.mapper.company.CompanyProjectMapper;
import com.info.zhiduoduo.repository.mapper.notice.CeoNoticeRecordMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerAccountMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerCompanyMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class CeoNoticeService {

	@Autowired
	CompanyProjectMapper companyProjectMapper;
	@Autowired
	CeoNoticeRecordMapper ceoNoticeRecordMapper;
	@Autowired
	PartnerAccountMapper partnerAccountMapper;
	@Autowired
	PartnerCompanyMapper partnerCompanyMapper;

	@Autowired
	DingdingNoticeService dingdingNoticeService;
	@Autowired
	CommonService commonService;

	/**
	 * 记录创客审核,24小时
	 *
	 * @param flag 0：创建 1：取消
	 */
	public void recordMakerVerify(int userid, int flag) {
		processRecordInternal(userid, flag, CeoNoticeType.MAKER_VERIFY, 24);
	}

	/**
	 * 记录企业审核
	 *
	 * @param flag 0：创建 1：取消
	 */
	public void recordCompanyVerify(int compid, int flag) {
		processRecordInternal(compid, flag, CeoNoticeType.COMPANY_VERIFY, 24);
	}

	/**
	 * 记录创客开税户
	 *
	 * @param flag 0：创建 1：取消
	 */
	public void recordMakerOpenTaxAcct(int userid, int flag) {
		processRecordInternal(userid, flag, CeoNoticeType.MAKER_OPEN_TAXACCT, 72);
	}

	/**
	 * 记录创客第一次交易开票。分有照无照
	 */
	public void recordFirstInvoice(int projectid, boolean hasPhoto) {
		int type = hasPhoto ? CeoNoticeType.HAS_PHOTO_FIRST_INVOICE : CeoNoticeType.NO_PHOTO_FIRST_INVOICE;
		int duration = hasPhoto ? 168 : 240;
		processRecordInternal(projectid, 0, type, duration);
	}

	/**
	 * 记录创客普通交易开票
	 */
	public void recordInvoice(int projectid) {
		processRecordInternal(projectid, 0, CeoNoticeType.NORMAL_INVOICE, 48);
	}

	/**
	 * 取消创客项目发票提醒
	 */
	public void cancelInvoiceNotice(int projectid) {
		ceoNoticeRecordMapper.cancelInvoiceNotice(projectid);
	}

	/**
	 * 创建ceo提醒检测，或者取消检测。
	 *
	 * @param bizid    业务id
	 * @param flag     flag 0：创建 1：取消
	 * @param type     业务类型
	 * @param duration 检测时长，单位小时
	 */
	private void processRecordInternal(int bizid, int flag, int type, int duration) {
		try {
			if (flag == 0) {
				ceoNoticeRecordMapper.del(type, bizid);
				Date expireDate = DateUtil.localDateTime2Date(LocalDateTime.now().plusHours(duration));
				new CeoNoticeRecord().setBizid(bizid)
						.setDuration(duration)
						.setState(1)
						.setType(type)
						.setCreatetime(new Date())
						.setExpiretime(expireDate)
						.insert();

			} else if (flag == 1) {
				ceoNoticeRecordMapper.cancelNotice(type, bizid);
			}
		} catch (Exception e) {
			log.error("创建ceo提醒检测，或者取消检测 报错: ", e);
		}
	}

	// ******************** 发送各种通知 *********************//

	public void checkCeoNotice() {
		List<CeoNoticeRecord> list = new CeoNoticeRecord().selectList(Condition.create().lt("expiretime", new Date()).eq("state", 1));
		if (CollectionUtils.isEmpty(list)) return;
		Map<Integer, Long> map = list.stream()
				.peek(record -> record.setState(2).updateById())
				.collect(Collectors.groupingBy(CeoNoticeRecord::getType, Collectors.counting()));

		String content = "昨日内部管理控制点：" + "\n创客注册24小时未审核数量：" + map.getOrDefault(CeoNoticeType.MAKER_VERIFY, 0L) + "\n企业注册24小时未审核数量：" +
				map.getOrDefault(CeoNoticeType.COMPANY_VERIFY, 0L) + "\n开税户后72小时未拿到执照数量：" +
				map.getOrDefault(CeoNoticeType.MAKER_OPEN_TAXACCT, 0L) + "\n创客首次交易168小时内未完成开票数量：" +
				map.getOrDefault(CeoNoticeType.HAS_PHOTO_FIRST_INVOICE, 0L) + "\n创客项目交易48小时内未完成开票数量：" +
				map.getOrDefault(CeoNoticeType.NORMAL_INVOICE, 0L);
		//微企通知胡刚和tina
		new Thread(() -> commonService.enterpriseAutomaticFreezing(28,content)).start();
		new Thread(() -> commonService.enterpriseAutomaticFreezing(44,content)).start();
//		dingdingNoticeService.sendNotice(GroupCode.NORMAL, content);
		/*list.stream().collect(Collectors.groupingBy(CeoNoticeRecord::getType, Collectors.counting())).forEach((type, count) -> {
			try {
				switch (type) {
					case CeoNoticeType.MAKER_VERIFY:

						break;
					case CeoNoticeType.COMPANY_VERIFY:

						break;
					case CeoNoticeType.MAKER_OPEN_TAXACCT:

						break;
					case CeoNoticeType.NO_PHOTO_FIRST_INVOICE:

						break;
					case CeoNoticeType.HAS_PHOTO_FIRST_INVOICE:

						break;
					case CeoNoticeType.NORMAL_INVOICE:

						break;
					default:
						break;
				}
			} catch (Exception e) {
			}
		});*/

	}

	/**
	 * //企业／创客注册24小时（一周七天）必须完成审核，否则推送消息；
	 */
	private void sendMakerVerify(CeoNoticeRecord record) {
		MakerAccount account = new MakerAccount().selectOne(Condition.create().eq("userid", record.getBizid()));
		if (account == null) {
			LogUtil.info("创客注册24小时未审核通知失败,userid = " + record.getBizid());
			return;
		}

		Maker maker = new Maker().selectById(record.getBizid());
		String content = "创客注册24小时未审核\n创客姓名：" + account.getRealname() + "\n电话：" + maker.getPhone() + "\n注册时间：" + DateUtil.getString(record.getCreatetime(), DateUtil.FORMAT_STYLE_1);
		//微企通知胡刚和tina
		new Thread(() -> commonService.enterpriseAutomaticFreezing(28,content)).start();
		new Thread(() -> commonService.enterpriseAutomaticFreezing(44,content)).start();
//		dingdingNoticeService.sendNotice(GroupCode.NORMAL, content);
	}

	/**
	 * //企业／创客注册24小时（一周七天）必须完成审核，否则推送消息；
	 */
	private void sendCompanyVerify(CeoNoticeRecord record) {
		Company company = new Company().selectById(record.getBizid());
		if (company == null) {
			LogUtil.info("企业注册24小时未审核通知失败,compid = " + record.getBizid());
			return;
		}
		String content = "企业注册24小时未审核\n企业名：" + company.getCompname() + "\n电话：" + company.getRegphone() + "\n注册时间：" + DateUtil.getString(record.getCreatetime(), DateUtil.FORMAT_STYLE_1);
		//微企通知胡刚和tina
		new Thread(() -> commonService.enterpriseAutomaticFreezing(28,content)).start();
		new Thread(() -> commonService.enterpriseAutomaticFreezing(44,content)).start();
//		dingdingNoticeService.sendNotice(GroupCode.NORMAL, content);
	}

	/**
	 * //创客点击开税户后72小时（3个工作日）必须拿到执照，否则推送消息；
	 */
	private void sendMakerOpenTaxAcct(CeoNoticeRecord record) {
		MakerAccount account = new MakerAccount().selectOne(Condition.create().eq("userid", record.getBizid()));
		MakerStudio studio = new MakerStudio().selectById(record.getBizid());
		if (account == null || studio == null) {
			LogUtil.info("开税户后72小时未拿到执照通知失败,userid = " + record.getBizid());
			return;
		}
		String content = "开税户后72小时未拿到执照\n创客姓名：" + account.getRealname() + "\n工作室名：" + studio.getUsername() + "\n电话：" + studio.getStudiophone() + "\n" + "注册时间：" + DateUtil.getString(record.getCreatetime(), DateUtil.FORMAT_STYLE_1);
		//微企通知胡刚和tina
		new Thread(() -> commonService.enterpriseAutomaticFreezing(28,content)).start();
		new Thread(() -> commonService.enterpriseAutomaticFreezing(44,content)).start();
//		dingdingNoticeService.sendNotice(GroupCode.NORMAL, content);
	}

	/**
	 * //无照创客首次交易后必须240小时（10日）完成开票否则推送消息；
	 */
	private void sendNoPhotoFirstInvoice(CeoNoticeRecord record) {
		CompanyProject project = new CompanyProject().selectById(record.getBizid());
		if (project == null) {
			LogUtil.info("无照创客首次交易240小时内未完成开票通知失败,projectid = " + record.getBizid());
			return;
		}
		MakerStudio studio = new MakerStudio().selectById(project.getUserid());

		String content = "无照创客首次交易240小时内未完成开票\n工作室名：" + studio.getUsername() + "\n电话：" + studio.getStudiophone() + "\n" + "注册时间：" + DateUtil.getString(record.getCreatetime(), DateUtil.FORMAT_STYLE_1);
		//微企通知胡刚和tina
		new Thread(() -> commonService.enterpriseAutomaticFreezing(28,content)).start();
		new Thread(() -> commonService.enterpriseAutomaticFreezing(44,content)).start();
//		dingdingNoticeService.sendNotice(GroupCode.NORMAL, content);
	}

	/**
	 * //有照创客首次交易必须１６８小时（７日）完成开票否则推送消息；
	 */
	private void sendHasPhotoFirstInvoice(CeoNoticeRecord record) {
		CompanyProject project = new CompanyProject().selectById(record.getBizid());
		if (project == null) {
			LogUtil.info("有照创客首次交易168小时内未完成开票通知失败,projectid = " + record.getBizid());
			return;
		}
		MakerStudio studio = new MakerStudio().selectById(project.getUserid());

		String content = "有照创客首次交易168小时内未完成开票\n工作室名：" + studio.getUsername() + "\n电话：" + studio.getStudiophone() + "\n" + "注册时间:" + DateUtil.getString(record.getCreatetime(), DateUtil.FORMAT_STYLE_1);
		//微企通知胡刚和tina
		new Thread(() -> commonService.enterpriseAutomaticFreezing(28,content)).start();
		new Thread(() -> commonService.enterpriseAutomaticFreezing(44,content)).start();
//		dingdingNoticeService.sendNotice(GroupCode.NORMAL, content);
	}

	/**
	 * //平时必须交易后48小时（2个工作日）完成开票否则推送消息；
	 */
	private void sendNormalInvoice(CeoNoticeRecord record) {
		CompanyProject project = new CompanyProject().selectById(record.getBizid());
		if (project == null) {
			LogUtil.info("普通创客项目交易48小时内未完成开票通知失败,projectid = " + record.getBizid());
			return;
		}
		MakerStudio studio = new MakerStudio().selectById(project.getUserid());

		String content = "普通创客项目交易48小时内未完成开票\n工作室名：" + studio.getUsername() + "\n电话：" + studio.getStudiophone() + "\n" + "注册时间：" + DateUtil.getString(record.getCreatetime(), DateUtil.FORMAT_STYLE_1);
		//微企通知胡刚和tina
		new Thread(() -> commonService.enterpriseAutomaticFreezing(28,content)).start();
		new Thread(() -> commonService.enterpriseAutomaticFreezing(44,content)).start();
//		dingdingNoticeService.sendNotice(GroupCode.NORMAL, content);
	}

	/**
	 * 每月初检查
	 * 1、企业客户自然月0交易预警发给商务（三个月0交易的预警给胡刚）
	 * 2、创客（11个月交易额低于10万元的预警给胡刚，3个月0交易的预警给赵菲）
	 */
	public void companyAndMakerTradeNotice() {
		Date lastMonth = DateUtil.getLastMonthBeginDate();
		Date threeMonthBegin = DateUtil.addMonth(lastMonth, -2);
		Date lastMonthEnd = DateUtil.getLastMonthEndDate();

		// 商务消息：上月0交易的企业客户有：**公司，****公司
		companyProjectMapper.getNoneTradeCompanyManagerByMonth(lastMonth).stream().collect(Collectors.groupingBy(CompanyManagerDto::getBusinessManagerId)).forEach((id, list) -> {
			try {
				if (CollectionUtils.isEmpty(list)) return;
				String names = list.stream().map(CompanyManagerDto::getCompname).collect(Collectors.joining(","));
				String info = "上月0交易的企业客户有：" + names;
				commonService.sendEnterpriseWeChatNotice(id, "", 1, info);
			} catch (Exception e) {
				log.info("商务消息id={}：上月0交易的企业客户 报错", id, e);
			}
		});

		// 胡刚消息：连续3个月0交易的企业有：**公司，****公司
		try {
			List<CompanyBriefDto> list = companyProjectMapper.getThreeMonthNoneTradeCompany(threeMonthBegin, lastMonthEnd);
			if (!CollectionUtils.isEmpty(list)) {
				int size = list.size();
				String names = list.stream().map(CompanyBriefDto::getCompname).collect(Collectors.joining(","));
				String info = "连续3个月0交易的企业共" + size + "个:" + names;
				commonService.sendEnterpriseWeChatNotice(0, "胡刚", 2, info);
			}
		} catch (Exception e) {
			log.info("发给胡刚：三个月0交易的企业客户 报错", e);
		}

		// 赵菲消息：3个月0交易的创客有：**创客1，****创客2
		try {
			List<MakerStudio> makerList = companyProjectMapper.getNoneTradeMaker(threeMonthBegin, lastMonthEnd);
			if (!CollectionUtils.isEmpty(makerList)) {
				int size = makerList.size();
				String names = makerList.stream().map(MakerStudio::getUsername).collect(Collectors.joining(","));
				String info = "3个月0交易的创客共" + size + "个:" + names;
				commonService.sendEnterpriseWeChatNotice(0, "赵菲", 2, info);
			}
		} catch (Exception e) {
			log.info("赵菲消息：3个月0交易的创客 报错", e);
		}

		// 胡刚消息：：11个月交易额低于10万元的创客有：**创客1，****创客2
		Date elevenMonthBegin = DateUtil.addMonth(lastMonth, -10);
		try {
			List<MakerStudio> makerList = companyProjectMapper.getNoneTradeMaker(elevenMonthBegin, lastMonthEnd);
			if (!CollectionUtils.isEmpty(makerList)) {
				int size = makerList.size();
				String names = makerList.stream().map(MakerStudio::getUsername).collect(Collectors.joining(","));
				String info = "11个月交易额低于10万元的创客共" + size + "个:" + names;
				commonService.sendEnterpriseWeChatNotice(0, "胡刚", 2, info);
			}
		} catch (Exception e) {
			log.info("胡刚消息：：11个月交易额低于10万元的创客 报错", e);
		}
	}

	public void checkPartnerExpireInOneWeek() {
		// 期满前一周发消息提醒胡刚和商务经理
		Date date = DateUtil.addDay(DateUtil.nowDate(), 7);
		List<PartnerExpireDto> list = partnerAccountMapper.getPendingExpirePartnerList(null, null, null, date);
		if (CollectionUtils.isEmpty(list)) return;

		String infoTemp = "有%1$d个合伙人即将到期，（%2$s），请尽快处理";
		// 通知商务经理
		list.stream().collect(Collectors.groupingBy(PartnerBriefDto::getBusinessManagerId)).forEach((id, plist) -> {
			try {
				if (CollectionUtils.isEmpty(plist)) return;
				String names = plist.stream().map(PartnerBriefDto::getRealname).collect(Collectors.joining("，"));
				String info = String.format(infoTemp, plist.size(), names);
				commonService.sendEnterpriseWeChatNotice(id, "", 1, info);
			} catch (Exception e) {
				log.info("商务消息id={}：上月0交易的企业客户 报错", id, e);
			}
		});

		// 通知胡刚
		String partnerNames = list.stream().map(PartnerBriefDto::getRealname).collect(Collectors.joining("，"));
		String info = String.format(infoTemp, list.size(), partnerNames);
		commonService.sendEnterpriseWeChatNotice(0, "胡刚", 2, info);
	}

	public void checkPartnerCompanyExpireInOneWeek() {
		// 期满前一周发消息提醒胡刚和商务经理
		Date date = DateUtil.addDay(DateUtil.nowDate(), 7);
		List<PartnerCompanyExpireDto> list = partnerCompanyMapper.listPendingExpired(date);
		if (CollectionUtils.isEmpty(list)) return;

		// 通知胡刚
		String infoTemp = "有%1$d个合伙人企业分佣设置即将到期，（%2$s），请尽快处理";
		String partnerNames = list.stream().map(dto -> dto.getRealname() + " - " + dto.getCompname()).collect(Collectors.joining("，"));
		String info = String.format(infoTemp, list.size(), partnerNames);
		commonService.sendEnterpriseWeChatNotice(0, "胡刚", 2, info);
	}
}
